﻿//内网版本宏
#define LOCAL

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using TopVisionLog;

namespace RestAPI
{
    public partial class RestAPICommon
    {
#if LOCAL
        /// <summary>
        /// 服务器IP
        /// </summary>   
        public static string ServerIP = "122.112.226.4";//华为云"122.112.226.4" 鼎视内网"192.168.2.70"
#else
        /// <summary>
        /// 服务器IP
        /// </summary>  
        public static string ServerIP = "122.112.226.4";//华为云"122.112.226.4" 鼎视内网"192.168.2.70" 紫万阿里 = 42.121.120.234
#endif

        public static string ServerPort = ":8080";

        /// <summary>
        /// 服务地址
        /// </summary>
        public static string ServerPath
        {
            get { return "http://" + ServerIP + ServerPort; }
            set { }
        }

        /// <summary>
        /// 服务器名称
        /// </summary>
        public static string Services = "zwgw";
        /// <summary>
        /// 消息签名密钥
        /// </summary>
        public static string KEY = "";//rHFKvoJkTxTQoAKiyXlZhevllwvwtdvM   //123456

        public static string CallBackUrl
        {
            get { return "http://" + ServerIP + "/TopVisionWeb/app/videostream/confcallback"; }
            set { }
        }

        public static string CallBackPost
        {
            get { return "http://" + ServerIP + "/TopVisionWeb/app/videostream"; }
            set { }
        }

        public static string CallBackGW = "videostream";

        public static int postTimeOut = 2000;

        #region Post响应事件
        /// <summary>
        /// POST响应事件
        /// </summary>
        /// <param name="response"></param>
        public delegate void GetPostResponseHandler(string response);

        #endregion

        //static string GetUrl(string serverPath = ServerPath, string services = Services)
        //{
        //    return Path.Combine(serverPath, services);
        //}

        public static Dictionary<string, string> GetDictionaryByModel<T>(this T paramModel)
        {
            try
            {
                Dictionary<string, string> dicParam = new Dictionary<string, string>();
                var properties = paramModel?.GetType()?.GetProperties();
                foreach (var targetPro in properties)
                {
                    try
                    {
                        var propertyValue = paramModel.GetType().GetProperty(targetPro.Name).GetValue(paramModel, null);
                        if (!dicParam.ContainsKey(targetPro.Name))
                        {
                            string value = Convert.ToString(propertyValue);
                            if (value != string.Empty)
                                dicParam.Add(targetPro.Name.ToLower(), value);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
                return dicParam;
            }
            catch (Exception ex)
            {
                Console.WriteLine("GetDictionaryByModel error : " + ex.Message);

                return null;
            }
        }

        public static string TestUrl;

        /// <summary>
        /// Post提交
        /// </summary>
        /// <param name="pUrl"> Api请求地址</param>
        /// <param name="pParam">Api请求参数</param>
        /// <returns></returns>
        public static WebRequestError WebClientPost(string pUrl, string pParam, GetPostResponseHandler ResponseHandler = null)
        {
            //if (pParam.Contains("content"))
            //    Console.WriteLine("Url:" + pUrl + " Param:" + pParam);

            //if (string.IsNullOrEmpty(TestUrl) & pUrl.Contains("confmsg"))
            //{
            //    TestUrl = "Test Url : " + pUrl + "  param : " + pParam;
            //    TVLog.WriteLine(TestUrl);
            //}

            //Debug.WriteLine("开始请求服务器");

            //参数字符转byte
            //byte[] argsByte = Encoding.UTF8.GetBytes(args);
            string read = "";
            //服务器响应
            WebRequestError webError = WebRequestError.成功_200;
            try
            {
                ////建立post请求
                ////HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ServerPath + "/" + Services + "/" + pUrl);
                //HttpWebRequest request = (HttpWebRequest)WebRequest.Create(pUrl);
                //request.Method = "POST";
                ////request.ContentType = "application/json;charset=UTF-8";
                ////request.ContentType = "application/x-www-form-urlencoded";
                //request.ContentType = "multipart/form-data";
                //request.Timeout = postTimeOut;

                ////request.ContentLength = Encoding.UTF8.GetByteCount(pParam);
                //Stream myRequestStream = request.GetRequestStream();
                //StreamWriter myStreamWriter = new StreamWriter(myRequestStream);// Encoding.GetEncoding("utf-8")

                ////Debug.WriteLine("写入请求参数");
                //myStreamWriter.Write(pParam);
                //myStreamWriter.Close();
                //HttpWebResponse response = null;
                //using (response = (HttpWebResponse)request.GetResponse())
                //{
                //    using (Stream myResponseStream = response.GetResponseStream())
                //    {
                //        using (StreamReader streamReader = new StreamReader(myResponseStream))
                //        {
                //            read = streamReader.ReadToEnd();
                //            streamReader.Close();
                //            streamReader.Dispose();
                //        }
                //    }
                //}



                // x-www-form-urlencoded

                WebClientEX webClient = new WebClientEX();
                //webClient.Headers[HttpRequestHeader.ContentType] = "multipart/form-data";
                webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
                //webClient.Encoding = Encoding.UTF8;
                byte[] postData = Encoding.UTF8.GetBytes(pParam);
                read = Encoding.UTF8.GetString(webClient.UploadData(pUrl, "POST", postData));

                //HttpRequestClient client = new HttpRequestClient();

                //string[] args = pParam.Split('&');
                //for (int i = 0; i < args.Length; i++)
                //{
                //    //string[] values = args[i].Split('=');
                //    string key = args[i].Substring(0, args[i].IndexOf('='));
                //    string value = args[i].Substring(args[i].IndexOf('=') + 1);

                //    client.SetFieldValue(key, value);
                //}

                //client.Upload(pUrl, out read);


                //Form-Data

                //MultiPartFormUpload client = new MultiPartFormUpload();
                //NameValueCollection bodys = new NameValueCollection();
                //string[] args = pParam.Split('&');
                //for (int i = 0; i < args.Length; i++)
                //{
                //    //string[] values = args[i].Split('=');
                //    string key = args[i].Substring(0, args[i].IndexOf('='));
                //    string value = args[i].Substring(args[i].IndexOf('=') + 1);
                //    bodys.Add(key, value);
                //}
                //var respon = client.Upload(pUrl, new NameValueCollection() { }, bodys, new List<FileInfo>() { });
                //read = respon.ResponseBody;
            }
            catch (Exception ex)
            {
                string errorMsg = "Post error:" + ex.Message;

                Console.WriteLine(errorMsg);

                string error = new Regex(@"\d+").Match(ex.Message).Value;

                switch (error)
                {
                    case "400":
                        webError = WebRequestError.参数错误_400;
                        break;
                    case "401":
                        webError = WebRequestError.验签失败_401;
                        break;
                    case "403":
                        webError = WebRequestError.企业不存在或状态异常_403;
                        break;
                    case "404":
                        webError = WebRequestError.远程服务器未找到_404;
                        break;
                    case "500":
                        webError = WebRequestError.服务暂停_503;
                        break;
                    default:
                        webError = WebRequestError.类型错误;
                        break;
                }

                read = errorMsg;

                throw new Exception(ex.Message);
            }
            finally
            {
                if (ResponseHandler != null)
                    ResponseHandler.Invoke(read);
            }

            return webError;
        }

        /// <summary>
        ///排序后的参数列表
        /// </summary>
        /// <param name="paramsMap"></param>
        /// <returns></returns>
        public static String getParamSrc(Dictionary<string, string> paramsMap, string digest)
        {
            var vDic = (from objDic in paramsMap orderby objDic.Key ascending select objDic);
            StringBuilder str = new StringBuilder();
            foreach (KeyValuePair<string, string> kv in vDic)
            {
                string pkey = kv.Key;
                string pvalue = kv.Value;
                str.Append(pkey + "=" + pvalue.Replace("+", "%2B") + "&");
            }
            String result = str.ToString().Substring(0, str.ToString().Length - 1);
            if (!String.IsNullOrEmpty(digest))
            {
                result += "&digest=" + digest;
            }

            return result;
        }

        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="ConvertString"></param>
        /// <param name="StringLen">16，32默认为16位MD5加密</param>
        /// <returns></returns>
        public static string GetStrMd5(string ConvertString, int StringLen = 16)
        {
            MD5 md5 = MD5.Create();

            byte[] argsBytes = Encoding.UTF8.GetBytes(ConvertString);
            byte[] result = md5.ComputeHash(argsBytes);
            string argsStr = "";
            for (int i = 0; i < result.Length; i++)
            {
                argsStr += result[i].ToString("x2");
            }
            return argsStr;
        }

        /// <summary>
        /// 16进制编码字符串  如有大写字母转小写
        /// </summary>
        /// <param name="ConvertString"></param>
        /// <returns></returns>
        public static string Get16Str(string ConvertString)
        {
            return BitConverter.ToString(ASCIIEncoding.Default.GetBytes(ConvertString)).Replace("-", " ").ToLower();
        }
        /// <summary>
        /// 获取加密后的Digset值
        /// </summary>
        /// <param name="pDic"></param>
        /// <returns></returns>
        public static string GetParamWithDigset(Dictionary<string, string> pDic)
        {
            try
            {
                string strParam = getParamSrc(pDic, "");
                string strParam16 = GetStrMd5(strParam);
                strParam16 += KEY;
                strParam16 = GetStrMd5(strParam16);
                return getParamSrc(pDic, strParam16);
            }
            catch (Exception ex)
            {
                Console.WriteLine("GetParamWithDigset Error " + ex.Message);
                throw ex;
            }
        }

        /// <summary>
        /// 获取加密后的Digset值
        /// </summary>
        /// <param name="pDic"></param>
        /// <returns></returns>
        public static string GetDigset(Dictionary<string, string> pDic)
        {
            try
            {
                string strParam = getParamSrc(pDic, "");
                string strParam16 = GetStrMd5(strParam);
                strParam16 += KEY;
                strParam16 = GetStrMd5(strParam16);
                return strParam16;
            }
            catch (Exception ex)
            {
                Console.WriteLine("GetDigset Error " + ex.Message);
                throw ex;
            }
        }

        /// <summary>
        /// 计算时间戳
        /// </summary>
        /// <param name="idHead"></param>
        /// <returns></returns>
        public static string GetCallflowidWithTimeStamp(string idHead = "")
        {
            DateTime dt1 = new DateTime(1970, 1, 1);
            long timeStap = (long)((DateTime.Now - dt1).TotalMilliseconds);
            return timeStap.ToString();
        }
    }
}
